﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using blackhouse.JavaScript.JQuery;
using System.Web.Script.Serialization;

namespace blackhouse.Web.Controls {
	public class SelectFileControl : Control {

		#region Fields

		private DropDownList folders;
		private DropDownList files;
		private DirectoryInfo appRoot;
		private string parentFolder = "/";
		private DirectoryInfo selectedFolder;
		private string parsedSelectedFile = "";
		private string selectedFile = "";

		#endregion

		#region Properties

		public string FileMask { get; set; }

		public string ParentFolder {
			get { return this.parentFolder; }
			set { this.parentFolder = value; }
		}

		public string SelectedFile {
			get {
				if(!string.IsNullOrEmpty(this.Page.Request[this.files.UniqueID]))
					return this.Page.Request[this.files.UniqueID];
				else
					return this.selectedFile;
			}
			set { this.selectedFile = value; }
		}

		#endregion

		#region Control Members

		protected override void OnInit(EventArgs e) {
			base.OnInit(e);

			this.receiveGetFiles();
			this.EnsureChildControls();
		}

		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);

			this.addFiles();
			this.bindFolders();
			this.bindFiles(this.selectedFolder);

			folders.Attributes.Add("select_file", files.UniqueID);
		}

		protected override void CreateChildControls() {
			base.CreateChildControls();

			this.Controls.Add(new Label() { Text = "Folder: " });
			folders = new DropDownList();
			this.Controls.Add(folders);

			this.Controls.Add(new Label() { Text = "Pliki: " });
			files = new DropDownList();
			this.Controls.Add(files);

		}

		#endregion

		#region Methods

		private void receiveGetFiles() {
			string folder = this.Page.Request["getFiles"];
			if(!string.IsNullOrEmpty(folder)) {
				DirectoryInfo di = new DirectoryInfo(this.Page.Server.MapPath(folder));
				if(di.Exists) {
					this.appRoot = new DirectoryInfo(this.Page.Server.MapPath("/"));
					this.Page.Response.Clear();
					this.Page.Response.ContentType = "application/json";
					Dictionary<string, string> files = new Dictionary<string, string>();

					string fileMasks = this.FileMask;
					if(string.IsNullOrEmpty(fileMasks)) fileMasks = "*.*";
					foreach(string fileMask in fileMasks.Split('|')) {
						foreach(FileInfo file in di.GetFiles(fileMask)) {
							files.Add(file.FullName.ReplaceEx(this.appRoot.FullName, "/").ReplaceEx("\\", "/"), file.Name);
						}
					}
					JavaScriptSerializer jss = new JavaScriptSerializer();
					this.Page.Response.Write(jss.Serialize(files));
					this.Page.Response.End();
				}
			}
		}

		private void addFiles() {
			JQueryLibraries jql = new JQueryLibraries();
			jql.IncludeFileBasedOnJQuery("blackhouse.Web.Controls.select_file.js,blackhouse.Web");
		}

		private void bindFiles(DirectoryInfo path) {
			files.ClearSelection();
			files.Items.Clear();
			if(!string.IsNullOrEmpty(this.SelectedFile)) {
				FileInfo sf = new FileInfo(this.Page.Server.MapPath(this.SelectedFile));
				if(sf.Exists) {
					this.parsedSelectedFile = sf.Name;
				}
			}

			string fileMasks = this.FileMask;
			if(string.IsNullOrEmpty(fileMasks)) fileMasks = "*.*";


			foreach(string fileMask in fileMasks.Split('|')) {
				foreach(FileInfo file in path.GetFiles(fileMask)) {
					ListItem li = new ListItem(file.Name, file.FullName.ReplaceEx(this.appRoot.FullName, "/").ReplaceEx("\\", "/"));
					bool selected = file.Name == this.parsedSelectedFile;
					li.Selected = selected;
					files.Items.Add(li);
				}
			}
		}

		private void bindFolders() {
			this.appRoot = new DirectoryInfo(this.Page.Server.MapPath("/"));
			DirectoryInfo startPath = new DirectoryInfo(this.Page.Server.MapPath(this.ParentFolder));
			this.selectedFolder = startPath;
			if(!string.IsNullOrEmpty(this.SelectedFile)) {
				FileInfo sf = new FileInfo(this.Page.Server.MapPath(this.SelectedFile));
				if(sf.Exists) {
					this.selectedFolder = sf.Directory;
				}
			}
			this.folders.Items.Add(new ListItem(startPath.Name, this.absoluteWebPath(startPath.FullName)));
			this.addNestedFolders(startPath, 0);
		}

		private void addNestedFolders(DirectoryInfo parentDirectory, int level) {
			foreach(DirectoryInfo directory in parentDirectory.GetDirectories().OrderBy(d => d.Name)) {
				ListItem li = new ListItem(new string('_', level * 2) + "|- " + directory.Name, this.absoluteWebPath(directory.FullName));
				li.Selected = directory.FullName == this.selectedFolder.FullName;
				this.folders.Items.Add(li);
				this.addNestedFolders(directory, level + 1);
			}
		}

		private string absoluteWebPath(string psyhicalPath) {
			string path = psyhicalPath.ReplaceEx(this.appRoot.FullName, "/").ReplaceEx("\\", "/");
			if(path.StartsWith("//")) path = path.Substring(1);
			return path;
		}

		#endregion

	}
}